package com.example.demo.interceptor;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.example.demo.api.APIUtil;
import com.example.demo.util.Tool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * fileName:CommonInterceptor
 * description: 请求拦截器，处理跨域问题
 * author: LJV
 * createTime:2022/4/7 11:28
 * version:1.0.0
 */
@Slf4j
@Component
public class CommonInterceptor implements HandlerInterceptor {

    /**
     * 在业务处理器处理请求之前被调用 如果返回false
     * 从当前的拦截器往回执行所有拦截器的afterCompletion(),
     * 再退出拦截器链, 如果返回true 执行下一个拦截器,
     * 直到所有的拦截器都执行完毕 再执行被拦截的Controller
     * 然后进入拦截器链,
     * 从最后一个拦截器往回执行所有的postHandle()
     * 接着再从最后一个拦截器往回执行所有的afterCompletion()
     *
     * @param request
     * @param response
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws IOException {
        /*ServletRequestAttributes requestAttr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest httpServletRequest = requestAttr.getRequest();*/
//        String ip = Tool.getClientIp(httpServletRequest);
        ServletRequestAttributes requestAttr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest httpServletRequest = requestAttr.getRequest();
        String ip = Tool.getClientIp(httpServletRequest);
        log.info("当前请求的IP："+ip);
        //解决跨域问题
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept,token,sign,Authorization");

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept,token,sign,Authorization");

        //请求过滤
        if (request.getRequestURI().equals("/doc.html") ||
                request.getRequestURI().equals("/user/notify") ||
                APIUtil.isDoc(request.getRequestURI()) ||
                APIUtil.isjs(request.getRequestURI()) ||
                request.getRequestURI().equals("/api/errorToken") ||
                request.getRequestURI().equals("/api/errorTime") ||
                request.getRequestURI().equals("/swagger-resources") ||
                request.getRequestURI().equals("/content/adminlist") ||
                request.getRequestURI().equals("/user/redis") ||
                request.getRequestURI().equals("/content/downExcel") ||
                request.getRequestURI().equals("/user/getUploadFile") ||
                request.getRequestURI().equals("/web_order/wxnotify") ||
                request.getRequestURI().equals("/web_order/wxnotifymini") ||
                request.getRequestURI().equals("/web_order/alinotify") ||
                request.getRequestURI().equals("/aliPay") ||
                request.getRequestURI().equals("/web_order/aliPayOrder") ||
                request.getRequestURI().equals("/web_order/alipayOrderH5") ||
                request.getRequestURI().equals("/web_order/wechatPayOrderH5") ||
                request.getRequestURI().equals("/web_order/wxnotifyH5") ||
                request.getRequestURI().equals("/web_order/aliPay") ||
                request.getRequestURI().equals("/web_webuser/getUploadFile")||
                request.getRequestURI().equals("/web_webuser/getWxgzhUser")||
                request.getRequestURI().equals("/web_webuser/getWxgzh")||
                request.getRequestURI().equals("/getHtml") ||
                request.getRequestURI().equals("/code/captchaPng")||
                request.getRequestURI().equals("/code/captchaGif")||
                request.getRequestURI().equals("/code/captchaZ")||
                request.getRequestURI().equals("/code/captchaMath")
        ) {
            return true;
        }

        log.info("请求地址:" + request.getRequestURI());
        String token = request.getHeader("sign");
        if (StringUtils.isEmpty(token)) {
            token = (String) request.getParameter("sign");
        }
        System.out.println("请求头:" + token);
        if (token != null) {
            Map<String, String> map = new HashMap<String, String>();
            try {
                //转为map
                map = APIUtil.toMap(request);
                log.info("map:" + JSON.toJSONString(map));

            } catch (Exception e) {
                // TODO: handle exception
            }

            //校验sign
            boolean sts = APIUtil.pwd(token, map);

            if (!sts) {
                response.sendRedirect(request.getContextPath() + "/api/errorToken");
                return false;
            }
            System.err.println("end");
            return true;
        } else {
            response.sendRedirect(request.getContextPath() + "/api/errorToken");
            return false;
        }
    }

    // 在业务处理器处理请求执行完成后,生成视图之前执行的动作
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        log.info("执行了postHandle");
    }

    /**
     * 在DispatcherServlet完全处理完请求后被调用
     * 当有拦截器抛出异常时,
     * 会从当前拦截器往回执行所有的拦截器的afterCompletion()
     *
     * @param request
     * @param response
     * @param handler
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {
        log.info("执行了afterCompletion");
        /*System.out.println("ex.getMessage() = " + ex.getMessage());
        String stackTrace = ExceptionUtils.getStackTrace(ex);
        System.out.println("stackTrace = " + stackTrace);*/
    }

}
